//* Licensed Materials - Property of IBM * //* eu.abc4trust.pabce.1.14 * //* (C) Copyright IBM Corp. 2012. All Rights Reserved. * //* US Government Users Restricted Rights - Use, duplication or * //* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * //* * //* This file is licensed under the Apache License, Version 2.0 (the * //* "License"); you may not use this file except in compliance with * //* the License. You may obtain a copy of the License at: * //* http://www.apache.org/licenses/LICENSE-2.0 * //* Unless required by applicable law or agreed to in writing, * //* software distributed under the License is distributed on an * //* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * //* KIND, either express or implied. See the License for the * //* specific language governing permissions and limitations * //* under the License. * //*/**/**************************************************************** package eu.abc4trust.ri.ui.user.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.HashSet; import java.util.List; import java.util.StringTokenizer; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.w3c.dom.Document; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; import org.w3c.dom.ls.LSSerializer; import org.xml.sax.SAXException; public class XmlUtils { private static Schema abc4trustSchema = null; private static JAXBContext context = null; private static JAXBContext getContext() throws JAXBException { if(context==null) { context = JAXBContext.newInstance(eu.abc4trust.xml.ObjectFactory.class, eu.abc4trust.returnTypes.ObjectFactoryReturnTypes.class); //System.out.println(context.toString()); } return context; } private static Schema getSchema() { if(abc4trustSchema == null) { // this XSD includes original + ui json + pilot specifid + test InputStream xmlSchema_all = XmlUtils.class.getResourceAsStream("/xsd/schema-include-all.xsd"); SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // only include xsd once final HashSet<String> seen = new HashSet<String>(); // resolver will create 'one' scheame with all definitions... schemaFactory.setResourceResolver(new LSResourceResolver() { @Override public LSInput resolveResource(final String type, final String namespaceURI, final String publicId, final String systemId, final String baseURI) { if(! seen.add(systemId)) { return null; } final InputStream xmlSchema_included = XmlUtils.class.getResourceAsStream("/xsd/" + systemId ); return new LSInput() { @Override public void setSystemId(String systemId) { } @Override public void setStringData(String stringData) { } @Override public void setPublicId(String publicId) { } @Override public void setEncoding(String encoding) { } @Override public void setCharacterStream(Reader characterStream) { } @Override public void setCertifiedText(boolean certifiedText) { } @Override public void setByteStream(InputStream byteStream) { } @Override public void setBaseURI(String baseURI) { } @Override public String getSystemId() { return systemId; } @Override public String getStringData() { return null; } @Override public String getPublicId() { return publicId; } @Override public String getEncoding() { return null; } @Override public Reader getCharacterStream() { return null; } @Override public boolean getCertifiedText() { return false; } @Override public InputStream getByteStream() { return xmlSchema_included; } @Override public String getBaseURI() { return null; } }; } }); try { abc4trustSchema = schemaFactory.newSchema(new StreamSource(xmlSchema_all)); } catch (SAXException e) { throw new RuntimeException("Cannot load abc4trust schema: " + e.getMessage()); } } return abc4trustSchema; } @Deprecated public static Object getObjectFromXML(String string) throws JAXBException, UnsupportedEncodingException, SAXException { return getObjectFromXML(string, true); } @Deprecated public static Object getObjectFromXML(String string, boolean validate) throws JAXBException, UnsupportedEncodingException, SAXException { return getJaxbElementFromXml(string, validate).getValue(); } public static Object getObjectFromXML(InputStream inputStream, boolean validate) throws JAXBException, UnsupportedEncodingException, SAXException { return getJaxbElementFromXml(inputStream, validate).getValue(); } @Deprecated public static JAXBElement<?> getJaxbElementFromXml(String string, boolean validate) throws JAXBException, UnsupportedEncodingException, SAXException { InputStream inputStream = new ByteArrayInputStream(string.getBytes("UTF-8")); return getJaxbElementFromXml(inputStream, validate); } public static JAXBElement<?> getJaxbElementFromXml(InputStream inputStream, boolean validate) throws JAXBException, UnsupportedEncodingException, SAXException { JAXBContext jc = getContext(); Unmarshaller unmarshaller = jc.createUnmarshaller(); if (validate) { unmarshaller.setSchema(getSchema()); } Object object = unmarshaller.unmarshal(inputStream); JAXBElement<?> e = (JAXBElement<?>) object; return e; } public static String toXml(JAXBElement<?> element) throws JAXBException, SAXException { return toXml(element, true); } public static String toXml(JAXBElement<?> element, boolean validate) throws JAXBException, SAXException { ByteArrayOutputStream byteArrayOutputStream = toXmlAsBaos(element, validate); try { return byteArrayOutputStream.toString("UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } } // public static String toXmlFromObject(Object element) throws JAXBException, SAXException { // JAXBContext jaxbcontext = getContext(); // Marshaller marshaller = jaxbcontext.createMarshaller(); // marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new AbcNamespace()); // ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // marshaller.marshal(element, byteArrayOutputStream); // try { // return byteArrayOutputStream.toString("UTF-8"); // } catch (UnsupportedEncodingException e) { // throw new RuntimeException(e); // } // } // public static ByteArrayOutputStream toXmlAsBaos(JAXBElement<?> element, boolean validate) throws JAXBException, SAXException { JAXBContext jaxbcontext = getContext(); Marshaller marshaller = jaxbcontext.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new AbcNamespace()); if (validate) { marshaller.setSchema(getSchema()); } ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); marshaller.marshal(element, byteArrayOutputStream); return byteArrayOutputStream; } public static String toNormalizedXML(JAXBElement<?> el) throws JAXBException, ParserConfigurationException, SAXException, IOException { String s = toXml(el, true); ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes("UTF-8")); return toNormalizedXML(bais); } /** * Remove leading a trailing whitespace characters from each line of input * @param input * @return */ public static String trim(String input) { final String newlineDelimiters = "\n\r\f"; StringBuilder ret = new StringBuilder(); StringTokenizer st = new StringTokenizer(input, newlineDelimiters); while (st.hasMoreTokens()) { ret.append(st.nextToken().replaceAll("^\\s+", "").replaceAll("\\s+$", "")); ret.append('\n'); } return ret.toString(); } public static String toNormalizedXML(InputStream is) throws ParserConfigurationException, SAXException, IOException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); dbf.setCoalescing(true); dbf.setIgnoringElementContentWhitespace(true); dbf.setIgnoringComments(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(is); document.normalizeDocument(); document.getDocumentElement() .setAttributeNS( "http://www.w3.org/2001/XMLSchema-instance", "xsi:schemaLocation", "http://abc4trust.eu/wp2/abcschemav1.0 ../../../../../../../../../abc4trust-xml/src/main/resources/xsd/schema.xsd"); DOMImplementationLS domImplLS = (DOMImplementationLS) document.getImplementation(); LSSerializer serializer = domImplLS.createLSSerializer(); String xml = serializer.writeToString(document); return trim(xml); } /** * Given an object that is presumably a JAXBElement<clazz>, return object.getValue(). This method * is useful for parsing XML elements of type xs:any (but where you know the type is clazz). * * If object is not a JAXBElement<clazz>, return null else return * ((JAXBElement<?>)object).getValue() * * @param jaxbElement * @param clazz * @return */ public static Object unwrap(Object jaxbElement, Class<?> clazz) { if (jaxbElement instanceof JAXBElement<?>) { Object ret = ((JAXBElement<?>) jaxbElement).getValue(); if (clazz.isInstance(ret)) { return ret; } else { System.err.println("Cannot cast " + ret + " to class " + clazz + " (actual class is " + ret.getClass() + ")."); return null; // TODO(enr): Throw an exception here } } else if (clazz.isInstance(jaxbElement)) { return jaxbElement; } else { System.err.println("Cannot cast " + jaxbElement + " to class JAXBElement<?> or " + clazz + " (actual class is " + jaxbElement.getClass() + ")."); return null; // TODO(enr): Throw an exception here } } /** * Given a list of objects that presumably contains one and only one JAXBElement<clazz>, return * list.get(0).getObject(). This method is useful for parsing a sequence of XML elements of type * xs:any (but where you know that there is only one element of type clazz). * * If the list contains 0, or more than 2 elements, return null. If the first element of the list * is not a JAXBElement<clazz>, return null else return ((JAXBElement<?>)list.get(0)).getValue() * * @param jaxbElementList * @param clazz * @return */ public static Object unwrap(List<Object> jaxbElementList, Class<?> clazz) { if (jaxbElementList.size() == 1) { return unwrap(jaxbElementList.get(0), clazz); } else { System.err.println("Cannot unwrap " + jaxbElementList + ". Size is " + jaxbElementList.size() + " (expected 1)."); return null; // TODO(enr): Throw an exception here } } }